1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20
21 import com.google.common.annotations.GwtCompatible;
22
23 import java.util.Collection;
24 import java.util.List;
25 import java.util.ListIterator;
26 import java.util.RandomAccess;
27 import java.util.Set;
28 import java.util.SortedSet;
29
30
31
32
33
34
35
36 @GwtCompatible
37 final class Constraints {
38 private Constraints() {}
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public static <E> Collection<E> constrainedCollection(
53 Collection<E> collection, Constraint<? super E> constraint) {
54 return new ConstrainedCollection<E>(collection, constraint);
55 }
56
57
58 static class ConstrainedCollection<E> extends ForwardingCollection<E> {
59 private final Collection<E> delegate;
60 private final Constraint<? super E> constraint;
61
62 public ConstrainedCollection(
63 Collection<E> delegate, Constraint<? super E> constraint) {
64 this.delegate = checkNotNull(delegate);
65 this.constraint = checkNotNull(constraint);
66 }
67 @Override protected Collection<E> delegate() {
68 return delegate;
69 }
70 @Override public boolean add(E element) {
71 constraint.checkElement(element);
72 return delegate.add(element);
73 }
74 @Override public boolean addAll(Collection<? extends E> elements) {
75 return delegate.addAll(checkElements(elements, constraint));
76 }
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public static <E> Set<E> constrainedSet(
92 Set<E> set, Constraint<? super E> constraint) {
93 return new ConstrainedSet<E>(set, constraint);
94 }
95
96
97 static class ConstrainedSet<E> extends ForwardingSet<E> {
98 private final Set<E> delegate;
99 private final Constraint<? super E> constraint;
100
101 public ConstrainedSet(Set<E> delegate, Constraint<? super E> constraint) {
102 this.delegate = checkNotNull(delegate);
103 this.constraint = checkNotNull(constraint);
104 }
105 @Override protected Set<E> delegate() {
106 return delegate;
107 }
108 @Override public boolean add(E element) {
109 constraint.checkElement(element);
110 return delegate.add(element);
111 }
112 @Override public boolean addAll(Collection<? extends E> elements) {
113 return delegate.addAll(checkElements(elements, constraint));
114 }
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public static <E> SortedSet<E> constrainedSortedSet(
130 SortedSet<E> sortedSet, Constraint<? super E> constraint) {
131 return new ConstrainedSortedSet<E>(sortedSet, constraint);
132 }
133
134
135 private static class ConstrainedSortedSet<E> extends ForwardingSortedSet<E> {
136 final SortedSet<E> delegate;
137 final Constraint<? super E> constraint;
138
139 ConstrainedSortedSet(
140 SortedSet<E> delegate, Constraint<? super E> constraint) {
141 this.delegate = checkNotNull(delegate);
142 this.constraint = checkNotNull(constraint);
143 }
144 @Override protected SortedSet<E> delegate() {
145 return delegate;
146 }
147 @Override public SortedSet<E> headSet(E toElement) {
148 return constrainedSortedSet(delegate.headSet(toElement), constraint);
149 }
150 @Override public SortedSet<E> subSet(E fromElement, E toElement) {
151 return constrainedSortedSet(
152 delegate.subSet(fromElement, toElement), constraint);
153 }
154 @Override public SortedSet<E> tailSet(E fromElement) {
155 return constrainedSortedSet(delegate.tailSet(fromElement), constraint);
156 }
157 @Override public boolean add(E element) {
158 constraint.checkElement(element);
159 return delegate.add(element);
160 }
161 @Override public boolean addAll(Collection<? extends E> elements) {
162 return delegate.addAll(checkElements(elements, constraint));
163 }
164 }
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179 public static <E> List<E> constrainedList(
180 List<E> list, Constraint<? super E> constraint) {
181 return (list instanceof RandomAccess)
182 ? new ConstrainedRandomAccessList<E>(list, constraint)
183 : new ConstrainedList<E>(list, constraint);
184 }
185
186
187 @GwtCompatible
188 private static class ConstrainedList<E> extends ForwardingList<E> {
189 final List<E> delegate;
190 final Constraint<? super E> constraint;
191
192 ConstrainedList(List<E> delegate, Constraint<? super E> constraint) {
193 this.delegate = checkNotNull(delegate);
194 this.constraint = checkNotNull(constraint);
195 }
196 @Override protected List<E> delegate() {
197 return delegate;
198 }
199
200 @Override public boolean add(E element) {
201 constraint.checkElement(element);
202 return delegate.add(element);
203 }
204 @Override public void add(int index, E element) {
205 constraint.checkElement(element);
206 delegate.add(index, element);
207 }
208 @Override public boolean addAll(Collection<? extends E> elements) {
209 return delegate.addAll(checkElements(elements, constraint));
210 }
211 @Override public boolean addAll(int index, Collection<? extends E> elements)
212 {
213 return delegate.addAll(index, checkElements(elements, constraint));
214 }
215 @Override public ListIterator<E> listIterator() {
216 return constrainedListIterator(delegate.listIterator(), constraint);
217 }
218 @Override public ListIterator<E> listIterator(int index) {
219 return constrainedListIterator(delegate.listIterator(index), constraint);
220 }
221 @Override public E set(int index, E element) {
222 constraint.checkElement(element);
223 return delegate.set(index, element);
224 }
225 @Override public List<E> subList(int fromIndex, int toIndex) {
226 return constrainedList(
227 delegate.subList(fromIndex, toIndex), constraint);
228 }
229 }
230
231
232 static class ConstrainedRandomAccessList<E> extends ConstrainedList<E>
233 implements RandomAccess {
234 ConstrainedRandomAccessList(
235 List<E> delegate, Constraint<? super E> constraint) {
236 super(delegate, constraint);
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249 private static <E> ListIterator<E> constrainedListIterator(
250 ListIterator<E> listIterator, Constraint<? super E> constraint) {
251 return new ConstrainedListIterator<E>(listIterator, constraint);
252 }
253
254
255 static class ConstrainedListIterator<E> extends ForwardingListIterator<E> {
256 private final ListIterator<E> delegate;
257 private final Constraint<? super E> constraint;
258
259 public ConstrainedListIterator(
260 ListIterator<E> delegate, Constraint<? super E> constraint) {
261 this.delegate = delegate;
262 this.constraint = constraint;
263 }
264 @Override protected ListIterator<E> delegate() {
265 return delegate;
266 }
267
268 @Override public void add(E element) {
269 constraint.checkElement(element);
270 delegate.add(element);
271 }
272 @Override public void set(E element) {
273 constraint.checkElement(element);
274 delegate.set(element);
275 }
276 }
277
278 static <E> Collection<E> constrainedTypePreservingCollection(
279 Collection<E> collection, Constraint<E> constraint) {
280 if (collection instanceof SortedSet) {
281 return constrainedSortedSet((SortedSet<E>) collection, constraint);
282 } else if (collection instanceof Set) {
283 return constrainedSet((Set<E>) collection, constraint);
284 } else if (collection instanceof List) {
285 return constrainedList((List<E>) collection, constraint);
286 } else {
287 return constrainedCollection(collection, constraint);
288 }
289 }
290
291
292
293
294
295
296 private static <E> Collection<E> checkElements(
297 Collection<E> elements, Constraint<? super E> constraint) {
298 Collection<E> copy = Lists.newArrayList(elements);
299 for (E element : copy) {
300 constraint.checkElement(element);
301 }
302 return copy;
303 }
304 }